/**
 * 应用退出业务模块
 * 负责处理应用的退出、窗口销毁、资源清理等功能
 * @author LYC
 * @date 2025-09-13
 */

import { app, BrowserWindow, Tray } from 'electron'

/**
 * 应用退出管理器
 */
export class AppExitManager {
  private static instance: AppExitManager
  private mainWindow: BrowserWindow | null = null
  private loginWindow: BrowserWindow | null = null
  private tray: Tray | null = null
  private isQuitting: boolean = false

  private constructor() {
    // 私有构造函数，确保单例模式
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): AppExitManager {
    if (!AppExitManager.instance) {
      AppExitManager.instance = new AppExitManager()
    }
    return AppExitManager.instance
  }

  /**
   * 设置窗口引用
   */
  public setWindows(mainWindow: BrowserWindow | null, loginWindow: BrowserWindow | null): void {
    this.mainWindow = mainWindow
    this.loginWindow = loginWindow
  }

  /**
   * 设置托盘引用
   */
  public setTray(tray: Tray | null): void {
    this.tray = tray
  }

  /**
   * 更新主窗口引用
   */
  public setMainWindow(mainWindow: BrowserWindow | null): void {
    this.mainWindow = mainWindow
  }

  /**
   * 更新登录窗口引用
   */
  public setLoginWindow(loginWindow: BrowserWindow | null): void {
    this.loginWindow = loginWindow
  }

  /**
   * 销毁指定窗口
   */
  private destroyWindow(window: BrowserWindow | null, windowName: string): void {
    if (window && !window.isDestroyed()) {
      console.log(`Destroying ${windowName} window...`)
      window.destroy()
    }
  }

  /**
   * 销毁系统托盘
   */
  private destroyTray(): void {
    if (this.tray) {
      console.log('Destroying system tray...')
      this.tray.destroy()
      this.tray = null
    }
  }

  /**
   * 清理所有窗口资源
   */
  private cleanupWindows(): void {
    this.destroyWindow(this.mainWindow, 'main')
    this.destroyWindow(this.loginWindow, 'login')

    // 清空引用
    this.mainWindow = null
    this.loginWindow = null
  }

  /**
   * 清理所有资源
   */
  private cleanupResources(): void {
    console.log('Cleaning up application resources...')

    // 清理窗口
    this.cleanupWindows()

    // 清理托盘
    this.destroyTray()
  }

  /**
   * 优雅地隐藏所有窗口
   */
  public hideAllWindows(): void {
    console.log('Hiding all windows...')

    if (this.mainWindow && !this.mainWindow.isDestroyed() && this.mainWindow.isVisible()) {
      this.mainWindow.hide()
      console.log('Main window hidden')
    }

    if (this.loginWindow && !this.loginWindow.isDestroyed() && this.loginWindow.isVisible()) {
      this.loginWindow.hide()
      console.log('Login window hidden')
    }
  }

  /**
   * 显示可用的窗口
   */
  public showAvailableWindow(): void {
    console.log('Attempting to show available window...')

    if (this.mainWindow && !this.mainWindow.isDestroyed()) {
      this.mainWindow.show()
      this.mainWindow.focus()
      console.log('Main window shown')
    } else if (this.loginWindow && !this.loginWindow.isDestroyed()) {
      this.loginWindow.show()
      this.loginWindow.focus()
      console.log('Login window shown')
    } else {
      console.log('No windows available to show')
    }
  }

  /**
   * 检查是否有窗口可见
   */
  public hasVisibleWindow(): boolean {
    const mainVisible =
      this.mainWindow && !this.mainWindow.isDestroyed() && this.mainWindow.isVisible()
    const loginVisible =
      this.loginWindow && !this.loginWindow.isDestroyed() && this.loginWindow.isVisible()

    return !!(mainVisible || loginVisible)
  }

  /**
   * 获取当前活动窗口
   */
  public getActiveWindow(): BrowserWindow | null {
    if (this.mainWindow && !this.mainWindow.isDestroyed()) {
      return this.mainWindow
    }
    if (this.loginWindow && !this.loginWindow.isDestroyed()) {
      return this.loginWindow
    }
    return null
  }

  /**
   * 检查是否正在退出应用
   */
  public isApplicationQuitting(): boolean {
    return this.isQuitting
  }

  /**
   * 设置退出标志
   */
  public setQuittingFlag(quitting: boolean): void {
    console.log(`Setting quitting flag to: ${quitting}`)
    this.isQuitting = quitting
  }

  /**
   * 处理窗口关闭事件
   * 如果正在退出应用，允许关闭；否则只隐藏窗口
   */
  public handleWindowClose(event: Electron.Event, windowName: string): void {
    if (this.isQuitting) {
      console.log(`${windowName} window closing due to application quit`)
      // 允许窗口关闭
      return
    }

    // 阻止默认关闭行为，隐藏窗口
    event.preventDefault()
    if (windowName === 'main' && this.mainWindow) {
      this.mainWindow.hide()
      console.log('Main window hidden instead of closed')
    } else if (windowName === 'login' && this.loginWindow) {
      this.loginWindow.hide()
      console.log('Login window hidden instead of closed')
    }
  }

  /**
   * 完全退出应用
   * 这是主要的退出方法，会清理所有资源并退出应用
   */
  public quitApplication(): void {
    console.log('=== INITIATING APPLICATION QUIT SEQUENCE ===')

    try {
      // 设置退出标志，防止窗口关闭事件干扰
      this.isQuitting = true

      // 清理所有资源
      this.cleanupResources()

      // 退出应用
      console.log('Calling app.quit()...')
      app.quit()

      // 如果app.quit()没有立即生效，强制退出
      setTimeout(() => {
        console.log('Force quitting application...')
        process.exit(0)
      }, 2000)
    } catch (error) {
      console.error('Error during application quit:', error)
      // 强制退出
      console.log('Force quitting due to error...')
      process.exit(0)
    }
  }

  /**
   * 安全退出（带确认）
   * 可以在这里添加用户确认逻辑
   */
  public async safeQuit(): Promise<void> {
    console.log('Safe quit requested...')

    // 这里可以添加保存数据、用户确认等逻辑
    // 例如：检查是否有未保存的数据，询问用户是否确认退出等

    // 目前直接执行退出
    this.quitApplication()
  }

  /**
   * 重启应用
   */
  public restartApplication(): void {
    console.log('Restarting application...')

    try {
      // 清理资源但不退出，而是重启
      this.cleanupResources()

      // 重启应用
      app.relaunch()
      app.quit()
    } catch (error) {
      console.error('Error during application restart:', error)
      // 如果重启失败，尝试正常退出
      this.quitApplication()
    }
  }

  /**
   * 处理macOS的应用激活事件
   */
  public handleAppActivation(createLoginWindowCallback?: () => BrowserWindow): void {
    console.log('App activated (dock icon clicked)')

    // 显示现有窗口
    if (this.mainWindow && !this.mainWindow.isDestroyed()) {
      console.log('Showing main window')
      this.mainWindow.show()
      this.mainWindow.focus()
    } else if (this.loginWindow && !this.loginWindow.isDestroyed()) {
      console.log('Showing login window')
      this.loginWindow.show()
      this.loginWindow.focus()
    } else if (createLoginWindowCallback) {
      // 如果没有窗口，创建登录窗口
      console.log('No windows exist, creating login window')
      const newLoginWindow = createLoginWindowCallback()
      this.setLoginWindow(newLoginWindow)
    }

    // 在 macOS 上显示 dock 图标
    if (process.platform === 'darwin') {
      app.dock?.show()
    }
  }

  /**
   * 处理所有窗口关闭事件
   */
  public handleAllWindowsClosed(): void {
    if (this.isQuitting) {
      console.log('All windows closed due to application quit')
      return
    }

    console.log('All windows closed, but app continues running in system tray')

    // 在某些平台上，可能需要特殊处理
    // 例如在 Windows/Linux 上可能需要完全退出
    // 但在 macOS 上通常保持应用运行

    if (process.platform !== 'darwin') {
      // 在非 macOS 平台上，如果没有托盘，则退出应用
      if (!this.tray) {
        console.log('No system tray available, quitting application')
        this.quitApplication()
      }
    }
  }

  /**
   * 强制退出应用（立即退出，不等待清理）
   */
  public forceQuit(): void {
    console.log('=== FORCE QUITTING APPLICATION ===')
    this.isQuitting = true
    process.exit(0)
  }
}

/**
 * 获取应用退出管理器的单例实例
 */
export const getAppExitManager = (): AppExitManager => {
  return AppExitManager.getInstance()
}

/**
 * 便捷的退出函数，保持向后兼容
 */
export const quitApp = (): void => {
  getAppExitManager().quitApplication()
}
